package com.xk.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cms.common.core.exception.ServiceException;
import com.cms.common.core.web.domain.Response;
import com.xk.domain.dto.CreationTimeDto;
import com.xk.domain.dto.PageDTO;
import com.xk.domain.dto.QueryYearDto;
import com.xk.domain.dto.UpdateYearDto;
import com.xk.domain.vo.YearTypeVo;
import com.xk.entity.YearType;
import com.xk.mapper.YearTypeMapper;
import com.xk.service.YearTypeService;
import com.xk.utils.BeanCopyUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 年度表(YearType)表服务实现类
 *
 * @author YaWu
 * @since 2024-12-14 23:52:52
 */
@Service("yearTypeService")
public class YearTypeServiceImpl extends ServiceImpl<YearTypeMapper, YearType> implements YearTypeService {

    @Override
    @Transactional
    public Response createYear(CreationTimeDto creationTimeDto) {
        //1.判断时间在是否合格
        if (creationTimeDto.getEndTime().before(creationTimeDto.getBeginTime())) {
            throw new ServiceException("考试结束时间必须大于考试开始时间",400);
        }
        YearType yearType = BeanCopyUtils.copyBean(creationTimeDto, YearType.class);
        //2.先获取全部年度
        List<YearType> list = this.list();
        //3.新增年度,不可以已存在的有如何交集和包含关系,必须是不交集的
        isNonOverlapping(yearType, list);
        //4.保存年度
        this.save(yearType);
        //5.返回成功信息
        return Response.success( "年度创建成功");
    }

    @Override
    public PageDTO<YearTypeVo> queryYear(QueryYearDto queryYearDto) {
        //1.分页查询
        Page<YearType> page = queryYearDto.toMpPageDefaultSortByCreateTimeDesc();
        LambdaQueryWrapper<YearType> wrapper = new LambdaQueryWrapper<YearType>()
                .like(StrUtil.isNotBlank(queryYearDto.getYearTypeName()), YearType::getYearTypeName, queryYearDto.getYearTypeName());
        this.page(page, wrapper);
        return PageDTO.of(page,e->{
            YearTypeVo yearTypeVo = BeanCopyUtils.copyBean(e, YearTypeVo.class);
            yearTypeVo.setBeginTime(DateUtil.formatDateTime(e.getBeginTime()))
                    .setEndTime(DateUtil.formatDateTime(e.getEndTime()))
                    .setCreateTime(DateUtil.formatDateTime(e.getCreateTime()))
                    .setUpdateTime(DateUtil.formatDateTime(e.getUpdateTime()));
            return yearTypeVo;
        });
    }

    @Override
    @Transactional
    public Response updateYear(UpdateYearDto updateYearDto) {
        //1.判断时间在是否合格
        if (updateYearDto.getEndTime().before(updateYearDto.getBeginTime())) {
            throw new ServiceException("考试结束时间必须大于考试开始时间",400);
        }
        YearType yearType = BeanCopyUtils.copyBean(updateYearDto, YearType.class);

        //2.先获取全部年度
        List<YearType> list = this.list();
        //去除自己
        List<YearType> collect = list.stream().filter(e -> !e.getYearTypeId().equals(yearType.getYearTypeId())).collect(Collectors.toList());
        //3.新增年度,不可以已存在的有如何交集和包含关系,必须是不交集的
        isNonOverlapping(yearType, collect);
        //4.更新年度,已删除(逻辑删除)的不更新
        boolean b = this.updateById(yearType);
        //5.返回成功信息
        return b?Response.success( "年度更新成功"):Response.error("年度更新失败");
    }

    /**
     * 检查YearType的时间是否与list中的YearType的时间不相交
     *
     * @param yearType 待验证的YearType
     * @param yearTypeList 年度列表
     * @return true表示时间不相交，false表示时间有交集
     */
    public static boolean isNonOverlapping(YearType yearType, List<YearType> yearTypeList) {
        Date newBeginTime = yearType.getBeginTime();
        Date newEndTime = yearType.getEndTime();

        for (YearType existing : yearTypeList) {
            Date existingBeginTime = existing.getBeginTime();
            Date existingEndTime = existing.getEndTime();

            // 判断是否存在交集
            if (!(newEndTime.before(existingBeginTime) || newBeginTime.after(existingEndTime))) {
                throw new ServiceException("你创建的<"+yearType.getYearTypeName()+">与<"+existing.getYearTypeName()+">的考试时间有交集,数据库的<"+existing.getYearTypeName()+">考试开始时间:"+ DateUtil.formatDateTime(existingBeginTime)+""+"考试结束时间:"+DateUtil.formatDateTime(existingEndTime),400);
            }
        }
        return true; // 全部无交集
    }


}

